package cn.remex.wechat.utils;

import cn.remex.RemexConstants;
import cn.remex.core.exception.ServiceCode;
import cn.remex.core.net.HttpHelper;
import cn.remex.core.util.*;
import cn.remex.wechat.WeChat;
import cn.remex.wechat.beans.WeChatReqXml;
import cn.remex.wechat.beans.WeChatResXml;
import cn.remex.wechat.beans.WeChatResult;
import cn.remex.wechat.config.WeChatApp;
import com.fasterxml.jackson.databind.JsonNode;

import java.io.InputStream;
import java.util.Map;
import java.util.function.Consumer;

/**
 * 名称：
 * 缩写：
 * 用途：
 * Created by yangy on 2016/8/24 0024.
 */
public class WeChatUtils {
	public enum WeChatApi{
		//================此枚举类需要和 wechat.properties文件中的后缀匹配=============//

		//mp&qy 均可用
		access_token,
		jsapi_ticket,
		oauth2_authorize,
		menu_create,
		menu_get,
		media_get,
		media_tmp_add,

		//mp可用
		oauth2_access_token,

		//qy可用
		userid_to_openid,
		getuserinfo,
		get_login_info,
		send_msg,


		//未整理
		customMsgSend,
		templatMsgSend,
		pulluserInfo,
		userInfo,
		qrcode_create,
		showqrcode,
		payUnifiedorder,
	}

	public static <R extends WeChatResXml, P extends WeChatReqXml> R invokeApiReturnXml(WeChatApp app, P requestXmlBean, Class<R> returnType, WeChatApi weChatApi, String... args) {
		String requestBody = XmlHelper.marshall(requestXmlBean);
		String result = requestServiceReturnString(app, requestBody, weChatApi, args);
		Assert.notNullAndEmpty(result, ServiceCode.FAIL, "微信支付响应为EMPTY，请联系管理员检查支付配置是否正确");
		R r = XmlHelper.unmarshall(returnType,result);
		Assert.isTrue(r != null && ("SUCCESS".equals(r.getErr_code()) || "SUCCESS".equals(r.getReturn_code())), ServiceCode.WEIXIN_CONFIG_ERROR, "调用微信服务错误:" + (Judgment.nullOrBlank(r.getErr_code_des())?r.getReturn_msg():r.getErr_code_des() ) );
		return r;
	}
	public static <T extends WeChatResult> T invokeApiReturnBean(WeChatApp app, String requestBody, Class<T> returnType, WeChatApi weChatApi, String... args) {
		String result = requestServiceReturnString(app, requestBody, weChatApi, args);
		T t =  JsonHelper.toJavaObject(result, returnType);
		Assert.isTrue(t != null && (Judgment.nullOrBlank(t.getErrcode()) || "0".equals(t.getErrcode())), ServiceCode.WEIXIN_CONFIG_ERROR, "调用微信服务错误:"+(t!=null?t.getErrmsg():"Reaponse Bean is NULL") );
		return t;
	}
	public static JsonNode invokeApiReturnJson(WeChatApp app, String requestBody, WeChatApi weChatApi, String... args) {
		String result = requestServiceReturnString(app, requestBody, weChatApi, args);
		JsonNode jsonNode = JsonHelper.toJsonNode(result);
		String errcode = JsonHelper.readString(jsonNode,"errcode");
		Assert.isTrue(Judgment.nullOrBlank(errcode) || "0".equals(errcode), ServiceCode.WEIXIN_CONFIG_ERROR,"调用微信服务错误:"+result);
		return jsonNode;
	}
	public static JsonNode invokeApiMultipartReturnJson(WeChatApp app, Map<String, Object> multiPart, WeChatApi weChatApi, String... args) {
		String result = requestServiceMultipartReturnString(app, multiPart, weChatApi, args);
		JsonNode jsonNode = JsonHelper.toJsonNode(result);
		String errcode = JsonHelper.readString(jsonNode,"errcode");
		Assert.isTrue(Judgment.nullOrBlank(errcode) || "0".equals(errcode), ServiceCode.WEIXIN_CONFIG_ERROR,"调用微信服务错误:"+result);
		return jsonNode;
	}
    public static void invokeApiHandleStream(WeChatApp app,String requestBody, Consumer<InputStream> consumer, WeChatApi weChatApi, String... args) {
        String url = String.format(WeChat.getApiUrl(app.getConfig().getType(), weChatApi), args);
        RemexConstants.logger.info("微信->API["+weChatApi+"],url="+url+";处理流");
        HttpHelper.send(url,httpCosumerEntity->{
            StringHelper.writeToStream(requestBody,"UTF-8",httpCosumerEntity.getOutputStream());
            consumer.accept(httpCosumerEntity.getInputStream());
        });
        RemexConstants.logger.info("微信->API["+weChatApi+"],url="+url+";处理流完成");

    }
	private static String requestServiceReturnString(WeChatApp app, String requestBody, WeChatApi weChatApi, String... args){
		String url = String.format(WeChat.getApiUrl(app.getConfig().getType(), weChatApi), args);
		RemexConstants.logger.info("微信->API["+weChatApi+"],url="+url+";requestBody="+requestBody);
		String result = HttpHelper.send(url,requestBody);
		RemexConstants.logger.info("微信->API["+weChatApi+"]:responseBody="+result);
		return result;
	}

	private static String requestServiceMultipartReturnString(WeChatApp app, Map<String, Object> multiPart, WeChatApi weChatApi, String... args){
		String url = String.format(WeChat.getApiUrl(app.getConfig().getType(), weChatApi), args);
		RemexConstants.logger.info("微信->API["+weChatApi+"]:responseBody="+multiPart);
		WebDavFileUtil.HttpResponseBean responseBean = WebDavFileUtil.doRequestHttpWithParams(url, WebDavFileUtil.HTTP_METHOD.POST, multiPart);
		String result = responseBean.getResult();
		RemexConstants.logger.info("微信->API["+weChatApi+"]:responseBody="+result);
		return result;
	}
}
